﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using System.Reflection;

namespace Qreed.Diagnostics
{
    /// <summary>
    /// Utility class for the Diagnostic namespace
    /// </summary>
    public static class DiagnosticsHelper
    {
        /// <summary>
        /// Gets the name of the calling function.
        /// </summary>
        /// <param name="skipFrames">The number of frames to skip.</param>
        /// <returns>The full name of the calling funtion.</returns>
        public static string GetCallingFunctionName(int skipFrames)
        {
            StackFrame s = new StackFrame(skipFrames, false);
            return string.Format("{0}.{1}", s.GetMethod().ReflectedType.FullName, s.GetMethod().Name);
        }

        /// <summary>
        /// Dumps the properties of an object to the debugger.
        /// </summary>
        /// <param name="target">The target object.</param>
        [Conditional("DEBUG")]
        public static void DebugWriteProperties(object target)
        {
            string s = DebugPropertiesToString(target);
            Trace.WriteLine(s);
        }

        /// <summary>
        /// Dumps the properties of an object to a string.
        /// </summary>
        /// <param name="target">The target object.</param>
        /// <returns>A formatted string with properties and values.</returns>
        public static string DebugPropertiesToString(object target)
        {
            StringBuilder sb = new StringBuilder();

            if (target != null)
            {
                Type t = target.GetType();

                sb.Append("target type: ");
                sb.AppendLine(t.Name);

                PropertyInfo[] props = t.GetProperties();

                foreach (PropertyInfo prop in props)
                {
                    sb.Append("    ");
                    sb.Append(prop.Name);
                    sb.Append(": ");

                    object v = prop.GetValue(target, null);

                    if (v == null)
                        sb.AppendLine("null");
                    else
                        sb.AppendLine(v.ToString());
                }
            }
            else
                sb.AppendLine("target type: null");

            return sb.ToString();
        }
    }
}
